# -*- coding: utf-8 -*-
# @Date：2024/9/30 11:47:30
# @Author：CJiaの青姝
# @FileName：cj_jwt
# @Editor：PyCharm2024
# @Remark：
import jwt
import time
import json
import decimal
import datetime

from jwt import exceptions
from django.core.cache import cache
from django.db import models

from backend.settings import SECRET_KEY, TOKEN_LIFETIME


class DateEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime.datetime):
            return obj.strftime('%Y-%m-%d %H:%M:%S')
        elif isinstance(obj, datetime.date):
            return obj.strftime("%Y-%m-%d")
        elif isinstance(obj, decimal.Decimal):
            return float(obj)
        else:
            return super(DateEncoder, self).default(obj)


class DateTimeFieldFormat(models.DateTimeField):
    """
    数据库datetime类型字段格式化(%Y-%m-%d %H:%M:%S)
    precision:需要保留的小数位数
    """

    def __init__(self, verbose_name=None, name=None, precision=0, **kwargs):
        self.precision = precision
        super().__init__(verbose_name, name, **kwargs)

    def db_type(self, connection):
        return 'datetime(%d)' % self.precision


# JWT加密 =>> token
def generate_token(payload):
    # 使用HS256算法对数据和密钥进行签名
    headers = {
        "type": "jwt",
        "alg": "HS256"
    }
    minutes = TOKEN_LIFETIME / 60
    timer = datetime.datetime.utcnow()
    # 设置过期时间
    payload['exp'] = timer + datetime.timedelta(minutes=minutes)
    # 加密信息
    result = jwt.encode(payload=payload, key=SECRET_KEY, algorithm="HS256", headers=headers)
    # 缓存Token
    cache.set(payload['email'] + "_Token", result, TOKEN_LIFETIME)
    # 返回加密结果
    return result


# token =>> 用户信息
def decode_token(token):
    # 自定义对象
    message = {"code": 0, "data": None, "msg": "操作成功"}
    try:
        userinfo = jwt.decode(token, SECRET_KEY, algorithms=['HS256'])
        # 返回解密结果
        message['data'] = userinfo
    except exceptions.ExpiredSignatureError:
        message['code'] = -1
        message['msg'] = "签名已过期, 请重新登录"
    except jwt.InvalidTokenError:
        message['code'] = -2
        message['msg'] = "无效的签名"
    return message
